package ar.edu.itba.pod.legajo47573;

import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import ar.edu.itba.pod.signal.source.RandomSource;

/**
 * Simple server that starts an RMI registry and binds the required objects
 */
public class Server {
	public static final String signalBindingName = "SignalProcessor";
	public static final String nodeBindingName = "SPNode";
	public static final String clusterName = "SignalsCluster";
	private final int port;
	private final int threads; 
	private NodeImpl node;

	public Server(int port, int threads) {
		super();
		this.port = port;
		this.threads = threads;
	}

	public void startServer() {
		Registry reg;
		try {
//			if(System.getSecurityManager() == null) {
//			     System.setSecurityManager(new RMISecurityManager());
//			}
			
			reg = LocateRegistry.createRegistry(port);
			
			node = new NodeImpl(threads);
			Remote proxy = UnicastRemoteObject.exportObject(node, 0);
			
			// Since the same implementation exports both interfaces, register the same
			// proxy under the two names
			reg.bind(signalBindingName, proxy);
			reg.bind(nodeBindingName, proxy);
			System.out.println("Server started and listening on port " + port);
			
			node.join(clusterName);
			
		} catch (RemoteException e) {
			System.out.println("Unable to start local server on port " + port);
			e.printStackTrace();
		} catch (AlreadyBoundException e) {
			System.out.println("Unable to register remote objects. Perhaps another instance is runnign on the same port?");
			e.printStackTrace();
		}
	}
	
	
	/**
	 * Simple cluster server.
	 * @param args Command line arguments: <port> of the node's RMI Registry <threads>
	 */
	public static void main(String[] args) throws RemoteException, NotBoundException {
		if (args.length < 2) {
			System.out.println("Command line parameters: Server <port> <threads>");
			return;
		}
		Server server = new Server(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
		server.startServer();
	}
	
}
